package com.cq.hd.app.controller;

import com.cq.hd.common.entity.AppLoginUser;
import com.cq.hd.common.entity.BusinessInfo;
import com.cq.hd.common.entity.UserInfo;
import com.cq.hd.common.enums.ResponseEnums;
import com.cq.hd.common.enums.biz.ActiveStateEnum;
import com.cq.hd.common.enums.biz.AgentStateEnum;
import com.cq.hd.common.pagination.Page;
import com.cq.hd.common.response.Result;
import com.cq.hd.common.response.ResultGenerator;
import com.cq.hd.common.response.Throw;
import com.cq.hd.common.utils.StringUtils;
import com.cq.hd.member.api.TbBusinessAgentApi;
import com.cq.hd.member.api.TbBusinessSubscribeApi;
import com.cq.hd.member.api.TbMerchantApi;
import com.cq.hd.member.api.TbUserBusinessApi;
import com.cq.hd.member.api.vo.MerchantVo;
import com.cq.hd.order.api.TbOrderApi;
import com.cq.hd.order.api.vo.ActiveAgentRankVo;
import com.cq.hd.product.api.TbActiveApi;
import com.cq.hd.product.api.dto.GoodsUseDetailsDto;
import com.cq.hd.product.api.vo.ActiveRedPacketBilListVo;
import com.cq.hd.product.api.dto.IndexActivePageDto;
import com.cq.hd.product.api.dto.UpdateActiveStateDto;
import com.cq.hd.product.api.vo.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.util.*;

@Slf4j
@RestController
@RequestMapping("/active")
@Api(tags = "活动相关接口")
public class ActiveController extends BaseController {

    @Autowired
    private TbActiveApi activeApi;

    @Autowired
    private TbBusinessSubscribeApi businessSubscribeApi;

    @Autowired
    private TbMerchantApi merchantApi;

    @Autowired
    private TbUserBusinessApi userBusinessApi;

    @Autowired
    private TbBusinessAgentApi tbBusinessAgentApi;

    @Autowired
    private TbOrderApi tbOrderApi;

    @ApiOperation(value = "首页活动列表")
    @ApiImplicitParam(name = "indexActivePageDto", value = "实体", paramType = "query", dataType = "IndexActivePageDto")
    @ApiResponse(response = IndexActivePageVo.class, code = 200, message = "接口返回对象参数")
    @GetMapping("/pageIndexActive")
    public Result<Page<IndexActivePageVo>> pageIndexActive(IndexActivePageDto indexActivePageDto) {
        AppLoginUser appLoginUser = getAppLoginUser();
        UserInfo userInfo = null;
        Long businessId = 0L;
        if (appLoginUser != null && appLoginUser.getUserId() != null) {
            indexActivePageDto.setUserId(appLoginUser.getUserId());
            userInfo = appLoginUser.getUserInfo();

            BusinessInfo businessInfo = userInfo.getBusinessInfo();
            if (businessInfo != null && businessInfo.getId() != null) {
                businessId = businessInfo.getId();
            }
        }

        // 类型：1-订阅，2-推荐(全部)，3-最新，4-推广
        // 订阅：获取用户订阅的商家信息，按活动发布时间降序显示
        // 推荐: 1、筛选当前城市进行中的活动，按销量降序（仅显示已订阅、购买过、浏览过的、是推广关系的商家的活动）
        //      2、在当前城市活动后，接上其他城市活动（按销量降序）（仅显示已订阅、购买过、浏览过的、是推广关系的商家的活动）
        // 最新：1、显示当前定位城市进行中的活动，按发布时间降序
        //      2、在1后面，拼接其他城市活动，按发布时间降序；
        //      以上仅显示已订阅、购买过、浏览过的、是推广关系的商家的活动
        Integer type = indexActivePageDto.getType();
        if (type == null) {
            type = 2;
        }
        List<Long> businessIds;
        if (type == 1) {
            if (appLoginUser == null || appLoginUser.getUserId() == null || appLoginUser.getUserId() <= 0) {
                Throw.isBusinessException(ResponseEnums.USER_ACCESS_DENIED);
            }

            // 根据userId查找订阅的商家列表
            businessIds = businessSubscribeApi.listByUserId(appLoginUser.getUserId()).unpack();
        } else if (type == 2) {
            // 2-全部 用户没登录，啥都没有
            if (appLoginUser == null || appLoginUser.getUserId() == null || appLoginUser.getUserId() <= 0) {
                return ResultGenerator.success(new Page<>());
            }

            // 获取用户关联的商家id
            businessIds = userBusinessApi.getBusinessIdsByUserId(appLoginUser.getUserId()).unpack();

            // 2-全部 也要包含可推广的，如果有推广权限，把可以推广的也列出来
            if (userInfo.getAgentState().equals(AgentStateEnum.OPEN.getValue())) {
                initAgentData(userInfo, indexActivePageDto);
                List<Long> agentBusinessIds = indexActivePageDto.getAgentBusinessIds();
                if (!CollectionUtils.isEmpty(agentBusinessIds)) {
                    Set<Long> mergedBusinessIdsSet = new HashSet<>(businessIds);
                    mergedBusinessIdsSet.addAll(agentBusinessIds);
                    businessIds = new ArrayList<>(mergedBusinessIdsSet);
                }
            }
        } else if (type == 4) {
            // 4-推广，没有推广权限的，直接返回空列表
            if (userInfo == null || userInfo.getAgentState().equals(AgentStateEnum.CLOSE.getValue())) {
                Throw.isBusinessException(ResponseEnums.USER_ACCESS_DENIED);
            }

            initAgentData(userInfo, indexActivePageDto);
            businessIds = indexActivePageDto.getAgentBusinessIds();

            indexActivePageDto.setAgentState(AgentStateEnum.OPEN.getValue());
        } else {
            // 用户没登录，啥都没有
            if (appLoginUser == null || appLoginUser.getUserId() == null || appLoginUser.getUserId() <= 0) {
                return ResultGenerator.success(new Page<>());
            }

            // 获取用户关联的商家id
            businessIds = userBusinessApi.getBusinessIdsByUserId(appLoginUser.getUserId()).unpack();
        }

        if (businessId > 0) {
            if (businessIds == null) {
                businessIds = new ArrayList<>();
            }
            businessIds.add(businessId);
            // 商家不看自己推广的
            if (type == 4) {
                indexActivePageDto.setExcludeBusinessIds(Collections.singletonList(businessId));
            }
        }

        if (CollectionUtils.isEmpty(businessIds) && userInfo.getAgentLevel() != 1) {
            return ResultGenerator.success(new Page<>());
        }
        // 一级经纪人，则可以看到所有分销活动
        if (type == 4 && userInfo.getAgentLevel() == 1) {
            businessIds = null;
        }

        indexActivePageDto.setSubscribeBusinessIds(businessIds);

        String cityName = indexActivePageDto.getCityName();
        if (StringUtils.isBlank(cityName)) {
            // 定位失败,返回默认城市
            indexActivePageDto.setCityName("厦门市");
        }

        return activeApi.pageIndexActive(indexActivePageDto);
    }

    private void initAgentData(UserInfo userInfo, IndexActivePageDto indexActivePageDto) {
        // 经纪人id
        Long agent1Id = 0L;
        Long agent2Id = 0L;
        if (userInfo.getAgentId() != null && userInfo.getAgentId() > 0) {
            agent1Id = userInfo.getAgentId();
            agent2Id = userInfo.getId();
            // 获取二级经纪人跟一级经纪人的佣金比例
            BigDecimal subAgentCommissionRate = tbBusinessAgentApi.getSubAgentCommissionRate(agent2Id, agent1Id).unpack();
            if (subAgentCommissionRate == null || subAgentCommissionRate.compareTo(BigDecimal.ZERO) < 0) {
                return;
            }
            log.error("二级经纪人佣金比例：{}, agent1Id: {}, agent2Id: {}", subAgentCommissionRate, agent1Id,agent2Id);
            indexActivePageDto.setSubAgentCommissionRate(subAgentCommissionRate);
        } else {
            agent1Id = userInfo.getId();
        }

        indexActivePageDto.setAgent1Id(agent1Id);
        indexActivePageDto.setAgent2Id(agent2Id);
        Integer sortType = indexActivePageDto.getSortType();
        if (sortType == null || sortType == 1) {
            indexActivePageDto.setType(2); // 销量
        } else {
            indexActivePageDto.setType(3); // 最新
        }
        // 经纪人关联的商家id
        List<Long> businessIds = tbBusinessAgentApi.myBusinessIds(agent1Id).unpack();
        if (businessIds != null && !businessIds.isEmpty()) {
            indexActivePageDto.setAgentBusinessIds(businessIds);
        }
    }

    @ApiOperation(value = "为你推荐（订单、活动底部）")
    @GetMapping("/recommendByBusinessId")
    public Result<List<IndexActivePageVo>> listRecommendActivesByBusinessId(Long businessId, Long curActiveId) {
        List<IndexActivePageVo> result = new ArrayList<>(6);

        // 查询当前商家的活动
        IndexActivePageDto indexActivePageDto = new IndexActivePageDto();
        indexActivePageDto.setPageNum(1);
        indexActivePageDto.setPageSize(20);
        indexActivePageDto.setType(2); // 设置2是为了按销量排序
        indexActivePageDto.setCityName("厦门市");
        indexActivePageDto.setSubscribeBusinessIds(Collections.singletonList(businessId));
        AppLoginUser appLoginUser = getAppLoginUser();
        if (appLoginUser != null && appLoginUser.getUserId() != null && appLoginUser.getUserId() > 0) {
            indexActivePageDto.setUserId(appLoginUser.getUserId());
        }

        Page<IndexActivePageVo> curBusinessActivePage = activeApi.pageIndexActive(indexActivePageDto).unpack();
        if (!CollectionUtils.isEmpty(curBusinessActivePage.getList())) {
            for (IndexActivePageVo indexActivePageVo : curBusinessActivePage.getList()) {
                if (Objects.equals(indexActivePageVo.getId(), curActiveId)) {
                    continue;
                }
                result.add(indexActivePageVo);
            }
        }

        // 如果不满6个，则查询订阅其他商家的活动
        if (result.size() < 6) {
            // 根据userId查找订阅的商家列表
            List<Long> businessIds = businessSubscribeApi.listByUserId(appLoginUser.getUserId()).unpack();
            if (!CollectionUtils.isEmpty(businessIds)) {
                businessIds.remove(businessId);
                if (!businessIds.isEmpty()) {
                    indexActivePageDto.setSubscribeBusinessIds(businessIds);
                    Page<IndexActivePageVo> subscribeBusinessActivePage = activeApi.pageIndexActive(indexActivePageDto).unpack();
                    if (!CollectionUtils.isEmpty(subscribeBusinessActivePage.getList())) {
                        for (IndexActivePageVo indexActivePageVo : subscribeBusinessActivePage.getList()) {
                            if (Objects.equals(indexActivePageVo.getId(), curActiveId)) {
                                continue;
                            }
                            result.add(indexActivePageVo);
                            if (result.size() == 6) {
                                break;
                            }
                        }
                    }
                }
            }
        }


        return ResultGenerator.success(result);
    }

    @ApiOperation(value = "活动详情")
    @ApiImplicitParam(name = "id", value = "活动id", paramType = "query", dataType = "Long")
    @ApiResponse(response = ActiveDetailsVo.class, code = 200, message = "接口返回对象参数")
    @GetMapping("/details")
    public Result<ActiveDetailsVo> details(Long id, String shareCode) {
        Long userId = 0L;
        AppLoginUser appLoginUser = getAppLoginUser();
        if (appLoginUser != null) {
            userId = appLoginUser.getUserId();
        }
        shareCode = Optional.ofNullable(shareCode).orElse("");
        return activeApi.details(id, userId, shareCode);
    }

    @ApiOperation(value = "活动可用红包列表")
    @ApiImplicitParam(name = "id", value = "活动id", paramType = "query", dataType = "Long")
    @ApiResponse(response = ActiveRedPacketBilListVo.class, code = 200, message = "接口返回对象参数")
    @GetMapping("/availableRedPacketList")
    public Result<List<ActiveRedPacketBilListVo>> availableRedPacketList(Long id) {
        AppLoginUser appLoginUser = getAppLoginUser();
        if (appLoginUser == null) {
            return ResultGenerator.success(new ArrayList<>());
        }
        return activeApi.availableRedPacketList(id, appLoginUser.getUserId());
    }

    @ApiOperation(value = "获取商品券的使用说明和可用商户")
    @ApiImplicitParam(name = "GoodsUseDetailsDto", value = "实体", paramType = "query", dataType = "Long")
    @ApiResponse(response = ActiveGoodsUseDetailsVo.class, code = 200, message = "接口返回对象参数")
    @GetMapping("/useDetails")
    public Result<ActiveGoodsUseDetailsVo> useDetails(GoodsUseDetailsDto goodsUseDetailsDto) {
        Long subOrderId = goodsUseDetailsDto.getSubOrderId();
        Long activeGoodsId = goodsUseDetailsDto.getActiveGoodsId();
        if ((subOrderId == null || subOrderId <= 0) && (activeGoodsId == null || activeGoodsId <= 0)) {
            Throw.isBusinessException("参数有误");
        }
        return activeApi.useDetails(goodsUseDetailsDto);
    }

    @ApiOperation(value = "获取商户的联系方式（只限于团购活动的非多商户商品）")
    @ApiImplicitParam(name = "merchantId", value = "商品商户id", paramType = "query", dataType = "Long")
    @ApiResponse(response = MerchantCustomVo.class, code = 200, message = "接口返回对象参数")
    @GetMapping("/getCustomInfo")
    public Result<MerchantCustomVo> getCustomInfo(Long merchantId) {
        if (merchantId == null || merchantId <= 0) {
            Throw.isBusinessException("请选择商品");
        }

        MerchantCustomVo merchantCustomVo = new MerchantCustomVo();
        MerchantVo merchantVo = merchantApi.getById(merchantId).unpack();
        if (merchantVo == null) {
            return ResultGenerator.error("未找到商户联系方式");
        }

        merchantCustomVo.setCustomerMobile(merchantVo.getCustomerMobile());
        merchantCustomVo.setCustomerWechat(merchantVo.getCustomerWechat());
        merchantCustomVo.setCustomerWechatUrl(merchantVo.getCustomerWechatUrl());

        return ResultGenerator.success(merchantCustomVo);
    }

    @ApiOperation(value = "前端活动起止时间倒计时到了调用,更新活动状态=已结束")
    @ApiResponse(response = Boolean.class, code = 200, message = "接口返回对象参数")
    @PostMapping("/updateEnd")
    public Result<Boolean> updateEnd(@RequestBody UpdateActiveStateDto updateActiveStateDto) {
        updateActiveStateDto.setActiveState(ActiveStateEnum.ENDED.getValue());
        return activeApi.updateActiveState(updateActiveStateDto);
    }

    @ApiOperation(value = "分销排行")
    @ApiImplicitParam(name = "id", value = "活动id", paramType = "query", dataType = "Long")
    @ApiResponse(response = ActiveDetailsVo.class, code = 200, message = "接口返回对象参数")
    @GetMapping("/agentRank")
    public Result<ActiveAgentRankVo> agentRank(Long id) {
        ActiveAgentRankVo activeAgentRankVo = new ActiveAgentRankVo();
        ActiveVo activeVo = activeApi.getById(id).unpack();
        AppLoginUser appLoginUser = getAppLoginUser();
        if (appLoginUser == null || appLoginUser.getUserInfo() == null || activeVo == null) {
            return ResultGenerator.success(activeAgentRankVo);
        }
        BusinessInfo businessInfo = appLoginUser.getUserInfo().getBusinessInfo();
        if (businessInfo == null || !businessInfo.getId().equals(activeVo.getBusinessId())) {
            return ResultGenerator.success(activeAgentRankVo);
        }

        return tbOrderApi.agentRank(id);
    }
}
